#ifndef _Figura2D_h
#define _Figura2D_h
#include <iostream>
#include "IDibujable.h"
#include "Coordenada.h"
#include "ExcepcionSVG.h"
using namespace std;

/** \file Figura2D.h
* \brief Definicion de clase
*
* Defincion de clase Figura2D.
* JAVIER ANTON DIAZ DNI:48629698Q
* STANISLAV LITVINENKO DNI:02062226T
*/

/** \brief Enum Color.
 *
 * No estoy seguro ni que hace aqui, ya que solo se usa como referencia porque no se puede convertir un int en un enum.
 */
enum Color{

	none,
	black,
	silver,
	gray,
	white,
	maroon,
	red,
	purple,
	fuchsia,
	green,
	lime,
	olive,
	yellow,
	navy,
	blue,
	teal,
	aqua

};

/** \brief Clase Figura2D.
 *
 * Clase que define los métodos y funciones asociados a esta.
 */
class Figura2D : public IDibujable {


	/** \brief Sobrecarga del operador "<<".
	*
	* Este método nos devuelve un ostream& en el que hemos escrito una salida según el formato svg, que hemos dispuesto.
	* \param os Tipo ostream&.
	* \param c Tipo Figura2D &.
	* \return El método devuelve un ostream&.
	*/
	friend ostream& operator<<(ostream&, const Figura2D&);

	public:
		/** \brief Constructor de objeto Figura2D.
		*
		* Pasamos varios argumentos, un objeto Coordenada porigen, para definer el centro de la figura y tres parametros de color.
		* Estos valores se encuentran definidos por defecto a su vez.
		* \param porigen de tipo Coordenada.
		* \param grosor de tipo int
		* \param fondo de tipo int
		* \param linea de tipo int
		*/
		Figura2D(Coordenada porigen = Coordenada(0,0), int grosor=1, Color fondo = black, Color linea = none);

		/** \brief Constructor de copia.
		*
		* Pasado un objeto crea uno igual a este sin alterarlo.
		* \param f Un objeto de tipo const Figura2d&.
		*/
		Figura2D(const Figura2D& f);

		/** \brief Sobrecarga del operador "=".
		*
		* Mediante este método, copiamos el contenido de un objeto circulo "f" a el que queramos.
		* \param f Tipo const Figura2D.
		* \return El método devuelve un objeto Figura2D.
		*/
		Figura2D& operator=(const Figura2D& f);

		/** \brief getOrigen.
		*
		* Este método devuelve el valor del atributo centro de la clase Figura2D.
		*
		* \return El método devuelve un objeto Coordenada.
		*/
		Coordenada getOrigen() const;

		/** \brief getFondo().
		*
		* Este método nos devuelve el valor del atributo fondo de nuestro objeto.
		*
		* \return El método devuelve un Color.
		*/
		Color getFondo() const;

		/** \brief getLinea().
		*
		* Este método nos devuelve el valor del atributo linea de nuestro objeto.
		*
		* \return El método devuelve un Color.
		*/
		Color getLinea() const;

		/** \brief getGrosorLinea().
		*
		* Este método nos devuelve el valor del atributo grosor de nuestro objeto.
		*
		* \return El método devuelve un int.
		*/
		int getGrosorLinea() const;

		/** \brief esAgrupada().
		*
		* Este método nos devuelve si es verdad que una figura pertenece a un grupo.
		*
		* \return El método devuelve un bool.
		*/
		bool esAgrupada() const;

		/** \brief mover().
		*
		* Este metodo desplaza el porigen de una figura a otra coordenada devolviendo la coordenada antigua.
		*
		* \param porigen El nuevo origen al que desplazar
		* \return El método devuelve la Coordenada antigua
		*/
		Coordenada mover(const Coordenada& porigen);

		/** \brief setFondo().
		*
		* Este método nos permite modificar el valor del fondo del objeto que lo llame.
		* \param pfondo tipo Color.
		* \return El método no devuelve nada.
		*/
		void setFondo(Color);

		/** \brief setLinea().
		*
		* Este método nos permite modificar el valor de linea del objeto que lo llame.
		* \param plinea tipo Color.
		* \return El método no devuelve nada.
		*/
		void setLinea(Color);

		/** \brief setGrosorLinea().
		*
		* Este método nos permite modificar el valor del grosor del objeto que lo llame.
		* \param pgrosor tipo int.
		* \return El método no devuelve nada.
		*/
		void setGrosorLinea(int);

		/** \brief setAgrupada().
		*
		* Este método nos permite modificar el valor de la variable protegida.
		* \param d tipo bool.
		* \return El método no devuelve nada.
		*/
		void setAgrupada(bool d = true);

		/** \brief puedoPintarme().
		*
		* Este metodo comprueba que la figura no pertenezca a ningun grupo y devuelve si es cierto o falso.
		* \return El método no devuelve nada.
		*/
		bool puedoPintarme() const;

		/** \brief pintar.
		*
		* Este método recibe un parámetro os tipo ostream mediante el cual efectúa la salida en el formato que queremos.
		* \param os tipo ostream&.
		* \return El método no devuelve nada.
		*/
		void pintar(ostream&) const;

		/** \brief leeEntrada().
		*
		* Este método procesa la linea del fichero para rellenar los datos de un Circulo.
		* \param is flujo de entrada.
		* \return El método no devuelve nada.
		*/
		void leeEntrada(istream&);

		/** \brief duplicar().
		*
		* Este método duplicar la figura con la Coordenada que recibe.
		* \param nuevoOrigen Coordenada de la figura duplicada
		* \return El método devuelve un puntero a la figura duplicada.
		*/
		Figura2D* duplicar(const Coordenada &);

		/** \brief Destructor virtual de objetos Figura2D.
		*
		* Definicion del destructor virtual que se heredara por los demas objetos.
		*/
		virtual ~Figura2D()=0;

	protected:
		/** \brief Variable tipo bool "agrupada";
		 *
		 *	La variable agrupada expresa la pertenencia de la figura a un grupo.
		 */
		bool agrupada;

	private:
		/** \brief Variable tipo int "grosorLinea";
		 *
		 *	La variable grosorLinea expresa el grosor de la linea que rodea la figura.
		 */
		int grosorLinea;

		/** \brief Variable tipo Color "colorFondo";
		 *
		 *	Esta variable representa el color que toma el fondo de la figura.
		 */
		Color colorFondo;

		/** \brief Variable tipo Color "colorLinea";
		 *
		 *	Esta variable representa el color que toma la linea que rodea la figura.
		 */
		Color colorLinea;

		/** \brief Variable tipo Coordenada "origen";
		 *
		 *	La variable lleva la coordenada en la que esta la figura.,
		 */
		Coordenada origen;

};
#endif
